﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using GrapplingHookGameData;

namespace GrapplingHookGame
{
    class HowToPlay
    {

        Texture2D mControllerFront;
        Texture2D mControllerTop;

        Viewport mViewport;
        ContentManager mContent;
        GraphicsDevice mGraphicsDevice;

        Vector2 mControllerFrontPosition;
        Vector2 mControllerTopPosition;

        SpriteFont mControllerText;

        public int YOffset { get; set; }

        Dictionary<Buttons, ControllerLine> mControllerLines;

        public string DPadText = string.Empty;

        public string LeftThumbStickText = string.Empty;
        public string RightThumbStickText = string.Empty;

        public string LeftShoulderText = string.Empty;
        public string RightShoulderText = string.Empty;

        public string LeftTriggerText = string.Empty;
        public string RightTriggerText = string.Empty;

        public string BackButtonText = string.Empty;
        public string StartButtonText = string.Empty;

        public string AButtonText = string.Empty;
        public string BButtonText = string.Empty;
        public string XButtonText = string.Empty;
        public string YButtonText = string.Empty;

        public byte AlphaFade { get; set; }
        
        bool mIsControllerTopDisplayed = true;
        
        public HowToPlay(ContentManager theContent, Viewport theViewport, GraphicsDevice theGraphicsDevice)
        {
            mViewport = theViewport;
            mContent = theContent;
            mGraphicsDevice = theGraphicsDevice;
            AlphaFade = 255;

            mControllerFront = theContent.Load<Texture2D>("con_front_ortho");
            mControllerTop = theContent.Load<Texture2D>("con_top_ortho");
            mControllerText = theContent.Load<SpriteFont>("ControllerText");
        
            PositionControllerImages();
            InitializeControllerLines();
        }

        private void PositionControllerImages()
        {
            mIsControllerTopDisplayed = true;
            if (LeftShoulderText == string.Empty && RightShoulderText == string.Empty
                && LeftTriggerText == string.Empty && RightTriggerText == string.Empty)
            {
                mIsControllerTopDisplayed = false;  
            }

            int aControllerTopHeight = 0;
            if (mIsControllerTopDisplayed)
            {
                aControllerTopHeight = mControllerTop.Height;
            }

            int aYPosition = YOffset + (int)((mViewport.Height - (aControllerTopHeight + mControllerFront.Height + 20)) / 2);

            mControllerFrontPosition.X = (int)((mViewport.Width - mControllerFront.Width) / 2);
            mControllerTopPosition.X = (int)((mViewport.Width - mControllerTop.Width) / 2);

            mControllerTopPosition.Y = aYPosition;
            mControllerFrontPosition.Y = aControllerTopHeight + mControllerTopPosition.Y + 20;
        }

        private void InitializeControllerLines()
        {
            int aYOffset = -YOffset;
            if (!mIsControllerTopDisplayed)
            {
                aYOffset += 100;
            }

            mControllerLines  = new Dictionary<Buttons, ControllerLine>();

            mControllerLines.Add(Buttons.DPadDown, new ControllerLine(new Vector2(279, 468 - aYOffset), new Vector2(565, 468 - aYOffset), mGraphicsDevice));

            mControllerLines.Add(Buttons.X, new ControllerLine(new Vector2(896, 345 - aYOffset), new Vector2(740, 385 - aYOffset), mGraphicsDevice));
            mControllerLines.Add(Buttons.Y, new ControllerLine(new Vector2(896, 305 - aYOffset), new Vector2(777, 350 - aYOffset), mGraphicsDevice));
            mControllerLines.Add(Buttons.A, new ControllerLine(new Vector2(896, 425 - aYOffset), new Vector2(776, 425 - aYOffset), mGraphicsDevice));
            mControllerLines.Add(Buttons.B, new ControllerLine(new Vector2(896, 385 - aYOffset), new Vector2(815, 385 - aYOffset), mGraphicsDevice));

            mControllerLines.Add(Buttons.Back, new ControllerLine(new Vector2(420, 270 - aYOffset), new Vector2(590, 390 - aYOffset), mGraphicsDevice));
            mControllerLines.Add(Buttons.Start, new ControllerLine(new Vector2(860, 270 - aYOffset), new Vector2(690, 390 - aYOffset), mGraphicsDevice));

            mControllerLines.Add(Buttons.LeftStick, new ControllerLine(new Vector2(380, 390 - aYOffset), new Vector2(505, 390 - aYOffset), mGraphicsDevice));
            mControllerLines.Add(Buttons.RightStick, new ControllerLine(new Vector2(928, 470 - aYOffset), new Vector2(703, 470 - aYOffset), mGraphicsDevice));

            mControllerLines.Add(Buttons.LeftShoulder, new ControllerLine(new Vector2(335, 208 - aYOffset), new Vector2(495, 208 - aYOffset), mGraphicsDevice));
            mControllerLines.Add(Buttons.RightShoulder, new ControllerLine(new Vector2(940, 208 - aYOffset), new Vector2(780, 208 - aYOffset), mGraphicsDevice));

            mControllerLines.Add(Buttons.LeftTrigger, new ControllerLine(new Vector2(350, 150 - aYOffset), new Vector2(510, 150 - aYOffset), mGraphicsDevice));
            mControllerLines.Add(Buttons.RightTrigger, new ControllerLine(new Vector2(925, 150 - aYOffset), new Vector2(765, 150 - aYOffset), mGraphicsDevice));
        }

        public void Draw(SpriteBatch theBatch)
        {
            //Reposition the Controller images and re-position all the lines
            PositionControllerImages();
            InitializeControllerLines();

            //fade color if applicable
            Color col = Color.White;
            col.A = AlphaFade;

            //Draw the Top and Front controller images. If any of the top buttons 
            //have been assigned text, then the top controller image
            //will be drawn, otherwise, just the front view will be drawn
            if (mIsControllerTopDisplayed)
            {
                theBatch.Draw(mControllerTop, mControllerTopPosition, col);
            }             
            theBatch.Draw(mControllerFront, mControllerFrontPosition, col);

            //Draw the controller text assigned for each button on the Controller
            DrawControllerText(DPadText, Buttons.DPadDown, theBatch, true);
            DrawControllerText(AButtonText, Buttons.A, theBatch, false);
            DrawControllerText(BButtonText, Buttons.B, theBatch, false);
            DrawControllerText(XButtonText, Buttons.X, theBatch, false);
            DrawControllerText(YButtonText, Buttons.Y, theBatch, false);            
            DrawControllerText(LeftThumbStickText, Buttons.LeftStick, theBatch, true);
            DrawControllerText(RightThumbStickText, Buttons.RightStick, theBatch, false);
            DrawControllerText(LeftTriggerText, Buttons.LeftTrigger, theBatch, true);
            DrawControllerText(RightTriggerText, Buttons.RightTrigger, theBatch, false);
            DrawControllerText(LeftShoulderText, Buttons.LeftShoulder, theBatch, true);
            DrawControllerText(RightShoulderText, Buttons.RightShoulder, theBatch, false);
            DrawControllerText(BackButtonText, Buttons.Back, theBatch, true);
            DrawControllerText(StartButtonText, Buttons.Start, theBatch, false);
        } 

        //Draw the ControllerLine and the Text that accompanies it
        private void DrawControllerText(string theButtonText, Buttons theButton, SpriteBatch theBatch, bool isLeft)
        {
            //fade color if applicable
            Color col = Color.Yellow;
            col.A = AlphaFade;

            if (theButtonText != string.Empty)
            {
                mControllerLines[theButton].Draw(theBatch, col);

                int aXPosition = 0;
                if (isLeft)
                {
                    aXPosition = (int)mControllerLines[theButton].Start.X - (int)mControllerText.MeasureString(theButtonText).X;
                }
                else
                {
                    aXPosition = (int)mControllerLines[theButton].Start.X;                 
                }

                int aYPosition = (int)mControllerLines[theButton].Start.Y - (int)(mControllerText.MeasureString(theButtonText).Y / 2);


                theBatch.DrawString(mControllerText, theButtonText, new Vector2(aXPosition, aYPosition), col);
            }
        }
    
    }

    class ControllerLine
    {
        private static LineBrush lineBrush = new LineBrush(2, Color.White);
        public Vector2 Start { get; private set; }
        public Vector2 End { get; private set; }

        public ControllerLine(Vector2 start, Vector2 end, GraphicsDevice graphicsDevice)
        {
            this.Start = start;
            this.End = end;
            lineBrush.Load(graphicsDevice);
        }

        public void Draw(SpriteBatch spriteBatch, Color color)
        {
            lineBrush.Draw(spriteBatch, Start, End, color);
        }
        public void Draw(SpriteBatch spriteBatch)
        {
            lineBrush.Draw(spriteBatch, Start, End);
        }
    }
}
